#!/usr/bin/env python3
"""
基于API逆向工程结果的完整Key Features提取器
使用Ford的official API获取完整的Key Features数据
"""

import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time
import json
import re

class CompleteFordKeyFeaturesExtractor:
    """完整的Ford Key Features提取器"""
    
    def __init__(self):
        self.driver = None
        self.setup_driver()
    
    def setup_driver(self):
        """设置Chrome浏览器"""
        chrome_options = Options()
        chrome_options.add_argument('--no-sandbox')
        chrome_options.add_argument('--disable-dev-shm-usage')
        chrome_options.add_argument('--disable-gpu')
        chrome_options.add_argument('--window-size=1920,1080')
        chrome_options.add_argument('--headless')  # 可以启用无头模式
        
        service = Service(ChromeDriverManager().install())
        self.driver = webdriver.Chrome(service=service, options=chrome_options)
    
    def get_catalog_and_series_from_url(self, url):
        """从URL中提取catalogId和series信息"""
        try:
            catalog_match = re.search(r'catalogId=([^&]+)', url)
            series_match = re.search(r'series=([^&]+)', url)
            
            if catalog_match and series_match:
                return catalog_match.group(1), series_match.group(1)
            return None, None
        except:
            return None, None
    
    def build_api_url(self, catalog_id, series_code):
        """构建Ford API URL"""
        base_url = "https://www.servicescache.ford.com/api/vehicle-model/v1/load"
        params = {
            'locale': 'en_GB',
            'retrieve': 'images,specs,featuresMkt,selectedMkt,featureImages,featureSpecs,keyFeatures,keyFeaturesModel,keyFeaturesWalkup,uscCodes,prices,featurePrices,content,packages',
            'feature': '',
            'config': f'{catalog_id}~{series_code}',
            'displayContext': 'VISTA',
            'suppressDisplayContext': 'true',
            'namedConfig': 'default'
        }
        
        param_string = '&'.join([f'{k}={v}' for k, v in params.items()])
        return f"{base_url}?{param_string}"
    
    def extract_key_features_from_api(self, url):
        """从Ford API提取完整的Key Features"""
        try:
            print(f"🔍 从API提取Key Features: {url}")
            
            # 先建立浏览器会话
            print("🌐 建立浏览器会话...")
            self.driver.get(url)
            
            # 等待页面加载
            WebDriverWait(self.driver, 15).until(
                EC.presence_of_element_located((By.TAG_NAME, 'body'))
            )
            
            # 处理Cookie
            try:
                cookie_buttons = self.driver.find_elements(By.CSS_SELECTOR, 'button[id*="cookie"], button[class*="cookie"]')
                for btn in cookie_buttons:
                    if btn.is_displayed():
                        btn.click()
                        time.sleep(1)
                        break
            except:
                pass
            
            print("✅ 浏览器会话已建立")
            
            # 从URL中提取参数
            catalog_id, series_code = self.get_catalog_and_series_from_url(url)
            if not catalog_id or not series_code:
                print("❌ 无法从URL提取catalogId和series参数")
                return []
            
            print(f"📋 提取到参数: catalogId={catalog_id}, series={series_code}")
            
            # 构建API URL
            api_url = self.build_api_url(catalog_id, series_code)
            print(f"🔗 API URL: {api_url}")
            
            # 使用JavaScript fetch获取API数据
            result = self.driver.execute_async_script(f"""
                var callback = arguments[arguments.length - 1];
                var url = '{api_url}';
                
                fetch(url, {{
                    method: 'GET',
                    headers: {{
                        'Accept': 'application/json',
                        'Content-Type': 'application/json'
                    }}
                }})
                .then(function(response) {{
                    if (response.ok) {{
                        return response.json();
                    }} else {{
                        throw new Error('HTTP ' + response.status);
                    }}
                }})
                .then(function(data) {{
                    callback(data);
                }})
                .catch(function(error) {{
                    callback({{ error: error.toString() }});
                }});
            """)
            
            if 'error' in result:
                print(f"❌ API请求失败: {result['error']}")
                return []
            
            print(f"✅ API请求成功，数据大小: {len(str(result))} 字符")
            
            # 提取Key Features
            key_features = self.extract_key_features_from_data(result)
            
            print(f"🎉 成功提取 {len(key_features)} 个Key Features:")
            for i, feature in enumerate(key_features):
                print(f"  {i+1}. {feature}")
            
            return key_features
            
        except Exception as e:
            print(f"❌ API提取失败: {e}")
            import traceback
            traceback.print_exc()
            return []
    
    def extract_key_features_from_data(self, data):
        """从API响应数据中提取Key Features"""
        key_features = []
        
        try:
            # 导航到keyFeatures.walkup.combined.features
            if ('data' in data and 
                'keyFeatures' in data['data'] and 
                'walkup' in data['data']['keyFeatures'] and
                'combined' in data['data']['keyFeatures']['walkup'] and
                'features' in data['data']['keyFeatures']['walkup']['combined']):
                
                features_list = data['data']['keyFeatures']['walkup']['combined']['features']
                
                for feature in features_list:
                    if 'descKf' in feature:
                        desc = feature['descKf']
                        if desc and desc.strip():  # 确保不是空字符串
                            key_features.append(desc.strip())
                
                print(f"✅ 从API数据中提取到 {len(key_features)} 个Key Features")
            else:
                print("❌ 在API数据中未找到keyFeatures路径")
                
        except Exception as e:
            print(f"❌ 解析Key Features数据失败: {e}")
        
        return key_features
    
    def get_car_models_with_complete_features(self, url):
        """获取所有车型及其完整的Key Features"""
        try:
            print(f"🚀 开始获取所有车型的完整Key Features...")
            
            # 访问主页面
            self.driver.get(url)
            WebDriverWait(self.driver, 15).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, 'div[data-cy][class*="ProductTile"]'))
            )
            
            # 处理Cookie
            try:
                cookie_buttons = self.driver.find_elements(By.CSS_SELECTOR, 'button[id*="cookie"], button[class*="cookie"]')
                for btn in cookie_buttons:
                    if btn.is_displayed():
                        btn.click()
                        time.sleep(2)
                        break
            except:
                pass
            
            # 获取所有车型
            car_models = []
            max_attempts = 10
            seen_models = set()
            
            for attempt in range(max_attempts):
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, 'div[data-cy][class*="ProductTile"]')
                    print(f"第{attempt+1}次尝试，找到 {len(elements)} 个车型元素")
                    
                    for element in elements:
                        data_cy = element.get_attribute('data-cy')
                        if data_cy and data_cy not in seen_models:
                            seen_models.add(data_cy)
                            
                            # 获取价格
                            try:
                                price_elem = element.find_element(By.CSS_SELECTOR, '[class*="price"], [data-cy*="price"]')
                                price = price_elem.text.strip()
                            except:
                                price = "未知价格"
                            
                            car_models.append({
                                'name': data_cy,
                                'price': price,
                                'key_features': []  # 将通过API填充
                            })
                    
                    # 尝试点击下一页
                    try:
                        next_btn = self.driver.find_element(By.CSS_SELECTOR, 'button[aria-label*="next"], button[action="next"]')
                        if next_btn.is_displayed():
                            next_btn.click()
                            time.sleep(2)
                        else:
                            break
                    except:
                        break
                        
                except Exception as e:
                    print(f"尝试 {attempt+1} 失败: {e}")
                    time.sleep(1)
            
            print(f"✅ 发现 {len(car_models)} 个不同的车型: {[m['name'] for m in car_models]}")
            
            # 为每个车型获取完整的Key Features
            for i, model in enumerate(car_models):
                print(f"\n🔍 获取车型 {i+1}/{len(car_models)}: {model['name']}")
                
                # 构建特定车型的API URL (这里使用通用的catalogId和series，实际应根据车型调整)
                catalog_id, series_code = self.get_catalog_and_series_from_url(url)
                
                # 对于不同车型，可能需要不同的series代码
                # 这里我们先用相同的API，在实际项目中需要映射每个车型到对应的series代码
                model_features = self.extract_key_features_from_api(url)
                model['key_features'] = model_features
                
                # 避免请求过于频繁
                time.sleep(1)
            
            return car_models
            
        except Exception as e:
            print(f"❌ 获取车型数据失败: {e}")
            import traceback
            traceback.print_exc()
            return []
    
    def cleanup(self):
        """清理资源"""
        if self.driver:
            self.driver.quit()

def test_complete_extractor():
    """测试完整的Key Features提取器"""
    
    print("🎯 测试基于API的完整Key Features提取器...")
    
    extractor = CompleteFordKeyFeaturesExtractor()
    
    try:
        # 测试URL
        url = "https://www.ford.co.uk/shop/build-your-ford/ngc2/ice2/model?catalogId=WAEGB-CGE-2022-FocusMCAGBR202450&series=ACMAA_VS-DH&planId=c"
        
        # 测试单个车型的Key Features提取
        print("\n📋 测试1: 提取Titanium的Key Features...")
        titanium_features = extractor.extract_key_features_from_api(url)
        
        # 与期望结果对比
        expected_features = [
            "16\" Alloy Wheels In High Gloss Finish",
            "13.2\" Touchscreen With SYNC4, Wireless Apple CarPlay / Android Auto Capability, FordPass Connect & Connected Navigation",
            "Keyless Entry & Start",
            "Fixed LED Headlamps, LED Daytime Running Lights & LED Rear Lights",
            "Quickclear heated windscreen",
            "Driver Assistance Technologies Including Front & Rear Parking Sensors And Cruise Control",
            "LED Rear Lights",
            "Electrically Operated, Heated, Power Fold Door Mirrors With Puddle Lamps And Side Indicators",
            "Grille With Chrome Surround And Horizontal Bars",
            "Dual-Zone Electronic Air Temperature Control (DEATC)",
            "Premium Sensico® Interior With Metal Grey Stitching",
            "Manual 4-Way Driver Seat Adjust, With Manual Lumbar Adjust",
            "Front And Rear Parking Sensors",
            "Lane-Keeping Aid With Lane-Keeping Assist",
            "Pre-Collision Assist With Autonomous Emergency Braking And Pedestrian/Cyclist Detection",
            "4.2\" Colour Tft Ice Blue Illumination Analogue Cluster With Trip Computer",
            "Thatcham Alarm With Power Door Dead Locks"
        ]
        
        print(f"\n📊 对比结果:")
        print(f"  期望特性数量: {len(expected_features)}")
        print(f"  实际提取数量: {len(titanium_features)}")
        print(f"  匹配度: {len(set(titanium_features) & set(expected_features))} / {len(expected_features)}")
        
        # 显示差异
        missing = set(expected_features) - set(titanium_features)
        extra = set(titanium_features) - set(expected_features)
        
        if missing:
            print(f"  缺少的特性: {len(missing)} 个")
            for feature in missing:
                print(f"    - {feature}")
        
        if extra:
            print(f"  额外的特性: {len(extra)} 个")
            for feature in extra:
                print(f"    + {feature}")
        
        if len(titanium_features) == len(expected_features) and not missing and not extra:
            print("🎉 完美匹配！API提取器工作正常！")
        
        # 保存结果
        result = {
            'test_url': url,
            'expected_count': len(expected_features),
            'actual_count': len(titanium_features),
            'match_count': len(set(titanium_features) & set(expected_features)),
            'expected_features': expected_features,
            'actual_features': titanium_features,
            'missing_features': list(missing),
            'extra_features': list(extra),
            'is_perfect_match': len(titanium_features) == len(expected_features) and not missing and not extra
        }
        
        with open('./release/complete_extractor_test_result.json', 'w', encoding='utf-8') as f:
            json.dump(result, f, ensure_ascii=False, indent=2)
        
        print(f"\n💾 测试结果已保存到: ./release/complete_extractor_test_result.json")
        
    except Exception as e:
        print(f"❌ 测试失败: {e}")
        import traceback
        traceback.print_exc()
        
    finally:
        extractor.cleanup()

if __name__ == "__main__":
    test_complete_extractor()
